package com.accessibleworlds.blind;

import java.util.ArrayList;

import com.accessibleworlds.R;
import com.accessibleworlds.util.Connections;
import com.accessibleworlds.util.SharedVariables;
import com.accessibleworlds.util.TextToSpeeches;
import com.accessibleworlds.util.TextToSpeechesGoogle;
import com.accessibleworlds.util.TextToSpeechesPico;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;

/**
 * Represents the create report class for a blind user.
 * @author Ayberk Özgür
 *
 */
public class BlindUserCreateReportPage extends Activity implements MultitouchGestureListener {
	private TextToSpeeches tts = null;
	private boolean ttsReady = false;
	private Thread connectionThread;
	private ArrayList<BlindUserMenuItem> spokenMenu = null;
	private int currentItem = 0;
	private int numberOfItems = 3;

	private double latitude, longitude;
	private boolean gotLocation = false;
	private LocationManager mlocManager;
	private LocationListener mlocListener;

	private String title = null;
	private int violationType = -1;

	private ProgressDialog progressDialog;
	private SharedPreferences preferences;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.blinduserpage);

		progressDialog = new ProgressDialog(this);
		progressDialog.setIndeterminate(true);
		progressDialog.setCancelable(false);

		preferences = getSharedPreferences(SharedVariables.fileName, MODE_PRIVATE);

		//Populate the spoken menu
		spokenMenu = new ArrayList<BlindUserMenuItem>();
		Intent intent;
		intent = new Intent(this,BlindUserSpeechToTextActivity.class);
		intent.putExtra("item_to_get", "title");
		intent.putExtra("language", "en-US");
		spokenMenu.add(new BlindUserMenuItem(this,getResources().getStringArray(R.array.blind_create_report_items)[0],intent,true));
		intent = new Intent(this,BlindUserSelectViolationType.class);
		spokenMenu.add(new BlindUserMenuItem(this,getResources().getStringArray(R.array.blind_create_report_items)[1],intent,true));
		spokenMenu.add(new BlindUserMenuItem(this,getResources().getStringArray(R.array.blind_create_report_items)[2],intent,false));

		connectionThread = new Thread(new Runnable() {
			public void run() {
				connection();
			}
		});
		connectionThread.start();

		mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		mlocListener = new BlindLocationListener();
		mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
	}

	@Override
	public void onBackPressed() {
	}

	private void connection() {
		if("0".equalsIgnoreCase(getResources().getStringArray(R.array.languageValues)[SharedVariables.currentLanguage]))
			tts = new TextToSpeechesPico();
		else
			tts = new TextToSpeechesGoogle();
		tts.speak(BlindUserCreateReportPage.this, getResources().getString(R.string.blind_create_report) + "Current item: " + spokenMenu.get(currentItem).getSpokenName());
		ttsReady = true;
	}

	public void multitouchMotionEvent(int numberOfFingers, GestureType gestureType) {
		if(ttsReady){
			tts.stopSpeaking();
			switch(gestureType){
			case DOWN:
				currentItem = (currentItem + 1) % numberOfItems;
				tts.speak(BlindUserCreateReportPage.this, spokenMenu.get(currentItem).getSpokenName());
				break;
			case UP:
				currentItem--;
				if(currentItem < 0)
					currentItem = numberOfItems - 1;
				tts.speak(BlindUserCreateReportPage.this, spokenMenu.get(currentItem).getSpokenName());
				break;
			case LEFT:
				finish();
				break;
			case RIGHT:
				if(currentItem == 2){
					if(title == null || title.equals(""))
						tts.speak(BlindUserCreateReportPage.this, "Please enter a title for the violation. ");
					else if(violationType < 0)
						tts.speak(BlindUserCreateReportPage.this, "Please select a violation type. ");
					else{
						tts.speak(BlindUserCreateReportPage.this, "Submitting the violation report...");
						(new CreateViolationReportTask()).execute(new Void[]{});
					}
				}
				else
					spokenMenu.get(currentItem).selectItem();
				break;
			}
		}
	}

	/* Class Blind Location Listener */
	private class BlindLocationListener implements LocationListener{
		public void onLocationChanged(Location loc){
			latitude = loc.getLatitude();
			longitude = loc.getLongitude();
			if(!gotLocation){
				tts.speak(BlindUserCreateReportPage.this, "Got your location. ");
				gotLocation = true;
			}
		}
		public void onProviderDisabled(String provider){
			while(!ttsReady);
			tts.speak(BlindUserCreateReportPage.this, "GPS is disabled. Please enable it to create a report. ");
		}
		public void onProviderEnabled(String provider){
			while(!ttsReady);
			tts.speak(BlindUserCreateReportPage.this, "GPS is enabled.");

			mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

			mlocListener = new BlindLocationListener();
			mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
		}
		public void onStatusChanged(String provider, int status, Bundle extras){

		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		String itemToGet = data.getExtras().getString("item_to_get");
		if(itemToGet.equals("title")){
			title = data.getExtras().getString("result");
			if(title.length() > 45){
				tts.speak(BlindUserCreateReportPage.this, "Title is too long, please try a shorter title. Current item: " + spokenMenu.get(currentItem).getSpokenName());
				title = null;
			}
			else
				tts.speak(BlindUserCreateReportPage.this, "Title was set successfully. Current item: " + spokenMenu.get(currentItem).getSpokenName());
		}
		else if(itemToGet.equals("violation_type")){
			violationType = data.getExtras().getInt("result");
			tts.speak(BlindUserCreateReportPage.this, "Violation type was set successfully. Current item: " + spokenMenu.get(currentItem).getSpokenName());
		}

		super.onActivityResult(requestCode, resultCode, data);
	}

	public class CreateViolationReportTask extends AsyncTask<Void, Integer, String> {
		private String [] takenData = null;

		protected void onPreExecute() {
			progressDialog.show();
		}

		@Override
		protected String doInBackground(Void... params) {
			if(Connections.serviceStatus()) {
				try {						
					String url = Connections.URI+Connections.createReport;
					String [] parameters = {"accessCode","userID","title","description","latitude","longitude","type","status"};

					String [] paramaterValues = {SharedVariables.accessCode,preferences.getString("userID", ""),title,"This report was entered by a viusally impaired user.",((int)(latitude*1000000))+"",((int)(longitude*1000000))+"",(violationType+1)+"","normal"};

					takenData = Connections.connection(url,parameters,paramaterValues);
					if("OK".equalsIgnoreCase(takenData[0])) {
						publishProgress(2);
						return "OK";
					}
					else {
						publishProgress(3);
					}						
				} catch (Exception e) {
					publishProgress(3);
				}
			}
			else {
				publishProgress(0);
			}
			return "Fail";
		}

		protected void onProgressUpdate(Integer... progress) {
			if(progress[0] == 0) {
				progressDialog.dismiss();
				tts.speak(BlindUserCreateReportPage.this, "Connection problem. Please try again.");
			}
			else if(progress[0]==2) {
				progressDialog.dismiss();
				(new Thread(new Runnable() {
					public void run() {
						tts.speak(BlindUserCreateReportPage.this, "Created report successfully.");
						while(tts.isSpeakingNow());
						BlindUserCreateReportPage.this.finish();
					}
				})).start();
			}
			else if(progress[0]==3) {
				progressDialog.dismiss();
				tts.speak(BlindUserCreateReportPage.this, "Connection problem. Please try again.");
			}
		}

		protected void onPostExecute(String result) {}
	}
}
